#ifndef BLIPCONT_H
#define BLIPCONT_H

#include "Blip.h"
#include <thread>
#include <mutex>

using std::thread;
using std::mutex;

class BlipController
{
public:
	BlipController( int num, int width, int height, int refresh, float gravity, float field, HWND * hwnd );
	~BlipController();

	HBITMAP * Tick();
	void SetNumBlips( int num );
	void SetGravity( float gravity );
	void SetField( float field );
	void SetSize( int width, int height );
	void SetPull( bool pull );
	void SetHWND( HWND * hwnd );
	void SetCTSOffset( POINT off );
	void SetClipping( bool clipping ) { m_clipping = clipping; }
	void SetStaticColor( bool color ) { m_staticColor = color; }
	bool GetClipping() { return m_clipping; }
	bool GetColor() { return m_staticColor; }
	int GetNumBlips() { return m_numBlips; }
	int GetField() { return m_field; }
	int GetGrav() { return m_grav; }
	void UpdateWell( POINT well_point );
	void Reset();
private:
	void RebuildBlipPositions();
	void BuildNewBitmap();
	void Worker( Blip * blips, int num, int worker );
	void CreateWorker( Blip * blips, int blips_num, int worker_num );
	void BitmapWorker( Blip * blips, int num );

	static void __cdecl WorkerWrapper( void * o, void * blips, void * num, void * worker )
    {
		static_cast<BlipController *>(o)->Worker( (Blip *)(blips), (int)(num), (int)(worker) );
    }
	static void __cdecl BuilderWrapper( void * o )
    {
		static_cast<BlipController *>(o)->BuildNewBitmap();
    }
	static void __cdecl BitmapWriter( void * o, void * blips, void * num )
	{
		static_cast<BlipController *>(o)->BitmapWorker( (Blip *)(blips), (int)(num) );
	}

	Blip		*	m_blips;
	int				m_numBlips;
	thread		*	m_thread;
	thread			m_bitmapThread;
	thread		*	m_bitmapWorkers;
	mutex		*	m_threadsMutex;
	int				m_numThreads;
	HBITMAP		*	m_hbitmapRet;
	HBITMAP		*	m_hbitmap;
	COLORREF	*	m_bitmapbits;
	HWND		*	m_hwnd;
	int				m_width;
	int				m_height;
	volatile bool	m_killThreads;
	bool			m_pull;
	bool			m_push;
	bool			m_staticColor;
	float			m_grav;
	float			m_field;
	int				m_refresh;
	BYTE			m_redOff;
	BYTE			m_greOff;
	BYTE			m_bluOff;
	POINT			m_off;
	POINT			m_well;
	float			m_fastestBlip;
	float			m_fps;
	volatile bool	m_busyResizing;
	bool			m_clipping;
	unsigned char	m_red, m_blue, m_green;
	//TODO: More Blip functions to give further control!
	//TODO: Add a bitmap handle for this class
	//TODO: Add a method to resize
	//TODO: Add methods for changing gravity strength and field size
	//TODO: Add push controls
	//TODO: Find more functional additions before working aesthetics
};


#endif //BLIPCONT_H